<template>
  <a-layout class="player-container relative" :style="{ width: '100%', height: '100%' }">
    <a-layout-content class="main-container" :class="isFullScreen ? 'fullscreen' : ''">
      <a-col key="col" :style="{ height: '100%' }" :span="24" class="player-box relative">
        <svg-icon size="large" name="videoPlayer" color="#657685" class="video-player__default" />
        <video-player
          ref="player"
          id="player"
          :rtspURL="rtspURL"
          :audioURL="audioURL"
          :isLive="isLive == 1"
          :isEncrypt="!!playConfigs.encryptMode"
          @play-progress-update="playProgressUpdate"
          @play-error="playError"
          @talk-start="talkStart"
          @play-file-over="playFileOver"
        />
      </a-col>
    </a-layout-content>
    <a-layout-footer
      class="w-full"
      :class="{ 'fullscreen-tool': isFullScreen, 'show-tools': isShowTools }"
    >
      <div class="flex items-center justify-center relative h-full">
        <svg-icon
          size="small"
          :color="isFullScreen ? '#fff' : '#657685'"
          class="mr-28 control-icon cursor-pointer"
          name="screenshot"
          :class="isDisabled ? 'disabled' : ''"
          @click="screenshot"
        />
        <svg-icon
          size="small"
          :color="isFullScreen ? '#fff' : '#657685'"
          class="mr-28 control-icon cursor-pointer"
          v-show="playConfigs.mode == 'live'"
          :class="isDisabled ? 'disabled' : ''"
          :name="isTalking ? 'intercomActive' : 'intercom'"
          @click="talk"
        />
        <!-- <a-dropdown placement="topLeft" @openChange="expand">
          <a class="ant-dropdown-link" @click.prevent>
            <svg-icon
              style="margin-top: 8px"
              size="small"
              :color="isFullScreen ? '#fff' : '#657685'"
              class="mr-28 control-icon cursor-pointer"
              v-show="playConfigs.mode != 'live'"
              :class="isDisabled ? 'disabled' : ''"
              name="doubleSpeed"
            />
          </a>
          <template #overlay>
            <a-menu v-model:selectedKeys="speed" :disabled="isDisabled">
              <a-menu-item v-for="item in speedArr" :key="item.value" @click="fast(item)">
                <a href="javascript:;">{{ item.key }}</a>
              </a-menu-item>
            </a-menu>
          </template>
        </a-dropdown> -->
        <svg-icon
          size="small"
          :color="isFullScreen ? '#fff' : '#657685'"
          class="mr-28 control-icon cursor-pointer"
          v-show="playConfigs.mode != 'live'"
          :class="isDisabled ? 'disabled' : ''"
          :name="!isPause ? 'pause' : 'play'"
          @click="togglePlay"
        />
        <svg-icon
          size="small"
          :color="isFullScreen ? '#fff' : '#657685'"
          class="mr-28 control-icon cursor-pointer"
          :class="isDisabled ? 'disabled' : ''"
          :name="isRecording ? 'videoClose' : 'video'"
          @click="record"
        />
        <svg-icon
          size="small"
          :color="isFullScreen ? '#fff' : '#657685'"
          class="mr-28 control-icon cursor-pointer"
          :class="isDisabled ? 'disabled' : ''"
          :name="isMuting ? 'soundClose' : 'sound'"
          @click="toggleMute"
        />
        <svg-icon
          size="small"
          :color="isFullScreen ? '#fff' : '#657685'"
          class="control-icon cursor-pointer"
          name="close"
          :class="isDisabled ? 'disabled' : ''"
          @click="closeVideo"
        />
        <svg-icon
          size="small"
          :color="isFullScreen ? '#fff' : '#657685'"
          class="control-icon cursor-pointer full-screen"
          :name="isFullScreen ? 'exitFullScreen' : 'fullScreen'"
          @click="toggleScreen"
        />
      </div>
    </a-layout-footer>
  </a-layout>
</template>

<script setup name="VideoDemo">
import {
  Layout as ALayout,
  LayoutContent as ALayoutContent,
  Col as ACol,
  LayoutFooter as ALayoutFooter,
  Dropdown as ADropdown,
  Menu as AMenu,
  MenuItem as AMenuItem,
  message,
} from 'ant-design-vue'
import videoPlay from '@/components/videoPlayer/videoPlay.js'
import { aesEncrypt } from '@/utils/tools'
import { useI18n } from 'vue-i18n'
import { timeFormat } from '@utils/tools'
import { openApiFetch } from '@utils/tools'
import { nextTick } from 'vue'
const { t } = useI18n()

const props = defineProps({
  playConfig: {
    type: Object,
  },
})

const playConfigs = ref({
  mode: 'live',
  protoType: 'rtsp',
  encryptMode: 0,
  businessType: 'localRecord',
  deviceId: '',
  channelId: '',
  beginTime: `${timeFormat(new Date(), 'Y-M-D')} 00:00:00`,
  endTime: `${timeFormat(new Date(), 'Y-M-D')} 23:59:59`,
  streamType: '0',
  assistStream: true,
  globalUser: '',
  accessKey: '',
  devCode: '',
  sk: '',
})

const isDisabled = computed(() => {
  return !playConfigs.value.channelId || !isPlay.value
})

const emits = defineEmits(['screenChange'])
let base_url = ''
// Playback object
const player = ref()
// Is it playing
const isPlay = ref(false)
// Is there a conversation going on
const isTalking = ref(false)
// Double speed
const speed = ref([1])
const speedArr = ref([
  {
    key: '1/8',
    value: 0.125,
  },
  {
    key: '1/4',
    value: 0.25,
  },
  {
    key: '1/2',
    value: 0.5,
  },
  {
    key: '1',
    value: 1,
  },
  {
    key: '2',
    value: 2,
  },
  {
    key: '4',
    value: 4,
  },
  {
    key: '8',
    value: 8,
  },
  {
    key: '16',
    value: 16,
  },
])

const isShowTools = ref(false)
const expand = (isOpen) => {
  isShowTools.value = isOpen
}

/**
 * @method screenshot screenshot
 */
const screenshot = () => {
  if (isDisabled.value) return
  player.value && player.value.screenshot()
}

/**
 * @method closeVideo Turn off playback
 */
const closeVideo = () => {
  if (isDisabled.value) return
  if (isRecording.value) {
    isRecording.value = !isRecording.value
    player.value && player.value.record()
  }
  speed.value = [1]
  isPlay.value = false
  isTalking.value = false
  player.value && player.value.close()
}

// Is recording in progress
const isRecording = ref(false)
/**
 * @method record Real time recording
 */
const record = async () => {
  if (isDisabled.value) return
  isRecording.value = !isRecording.value
  player.value && player.value.record()
}

const audioURL = ref(null)
const rtspURL = ref('')
const getTalk = () => {
  if (!playConfigs.value.channelId || playConfigs.value.mode != 'live' || !isPlay.value) return
  const params = {
    deviceId: playConfigs.value.deviceId,
    channelId: playConfigs.value.channelId,
    businessType: 'talk',
    streamType: playConfigs.value.streamType,
    protoType: playConfigs.value.protoType,
    encryptMode: playConfigs.value.encryptMode,
    // devCode: aesEncrypt(playConfigs.value.devCode, playConfigs.value.sk, '86E2DB6D77B5E9CD'),
    accessKey: playConfigs.value.accessKey,
  }
  return new Promise((resolve, reject) => {
    fetch(`${base_url}/gateway/videobussiness/api/createDeviceStreamUrl`, {
      method: 'POST',
      body: JSON.stringify(params),
      // mode: 'no-cors',
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Content-Type': 'application/json',
        Authorization: 'Bearer ' + token.value,
      },
    })
      .then((res) => {
        return res.json()
      })
      .then((data) => {
        const url = data.data && data.data.url
        if (url) {
          audioURL.value = url
          nextTick().then(() => {
            isTalking.value = !isTalking.value
            player.value && player.value.talk()
          })
          resolve()
        } else {
          const errMsg = data.code == 'DV1019' ? '设备能力级不支持！' : data.errMsg
          // this.$message.warning(errMsg)
          console.log(errMsg)
          reject(errMsg)
        }
      })
  })
}
/**
 * @method talk Intercom
 */
const talk = () => {
  if (!isTalking.value) {
    getTalk()
  } else {
    isTalking.value = !isTalking.value
    player.value && player.value.talk()
  }
}

/**
 * @method talkStart Enable intercom callback
 */
const talkStart = () => {
  console.log('----------Enable intercom-----------')
}

/**
 * @method playFF Double speed
 */
const playFF = (rate) => {
  player.value && player.value.playFF(rate)
}

const isMuting = ref(false)
/**
 * @method toggleMute Sound control
 */
const toggleMute = () => {
  if (isDisabled.value) return
  isMuting.value = !isMuting.value
  const voiceVal = isMuting.value ? '0' : '1'
  player.value && player.value.setAudioVolume(voiceVal)
}

// let current = 0
const playProgressUpdate = (msg) => {
  if (!isPlay.value) {
    isPlay.value = true
  }
  // console.log('----------Current playback time------------:', msg.playTime)
  // console.log('----------The current playback time segment------------:', msg.time)
}
const playStart = () => {
  if (!isPlay.value) {
    isPlay.value = true
  }
}

const playError = (msg) => {
  let errMsg = ''
  switch (msg.errorCode) {
    case 500:
      errMsg = 'Failed to acquire the stream. The service is incorrect.'
    case 999:
      errMsg = 'No response. The service is disconnected.'
    case 504:
      errMsg = 'The voice talk service is unavailable.'
    case 503:
      errMsg = 'The service is unavailable.'
    case 404:
      errMsg = 'The stream address does not exist.'
    case 202:
      errMsg = 'Failed to connect to websocket.'
  }
  if (errMsg) {
    message.error(errMsg)
  }
}

const playFileOver = () => {
  isPlay.value = false
  console.log('-----------ended-------')
}

const isLive = ref(1)
/**
 * @method play play
 */
const play = async () => {
  // if (!props.playConfig.channelId) return
  // if (isGetUrl.value) return
  playConfigs.value = JSON.parse(JSON.stringify(props.playConfig))
  isLive.value = props.playConfig.mode == 'live' ? 1 : 0
  closeVideo()
  await init()
  nextTick().then(() => {
      player.value && player.value.play()
  })
}
/**
 * @method pause suspend
 */
const pause = () => {
  player.value && player.value.pause()
}
/**
 * @method start Continue playing
 */
const start = () => {
  player.value && player.value.start()
}

const isPause = ref(false)
const togglePlay = async () => {
  if (playConfigs.value.mode == 'live' || !isPlay.value) return
  if (!isPlay.value) {
    await init()
    player.value && player.value.play()
  } else if (isPause.value) {
    isPause.value = false
    start()
  } else {
    isPause.value = true
    pause()
  }
}

const isOpenIVS = ref(true)
/**
 * @method toggleIVS Intelligent frame control
 */
const toggleIVS = () => {
  if (!playConfigs.value.channelId) return
  isOpenIVS.value = !isOpenIVS.value
  if (isOpenIVS.value) {
    player.value.openIVS()
  } else {
    player.value.closeIVS()
  }
}
const fast = (item) => {
  if (isDisabled.value) return
  const rate = item.value
  speed.value = [item.value]
  playFF(rate)
}

const isGetUrl = ref(false)

// Full screen or not
const isFullScreen = ref(false)
const toggleScreen = () => {
  // Switch full screen (full screen display as true, window display as false)
  isFullScreen.value = !isFullScreen.value
  emits('screenChange', isFullScreen.value)
}

const init = () => {
  let param = {
    deviceId: playConfigs.value.deviceId,
    channelId: playConfigs.value.channelId,
    streamType: playConfigs.value.streamType,
    protoType: playConfigs.value.protoType,
    encryptMode: '0',
  }
  if (playConfigs.value.mode == 'live') {
    param.businessType = 'real'
  } else {
    param.businessType = 'localRecord'
    param.beginTime = playConfigs.value.beginTime
    param.endTime = playConfigs.value.endTime
  }

  return new Promise((resolve, reject) => {
    fetch(`${base_url}/gateway/videobussiness/api/createDeviceStreamUrl`, {
      method: 'POST',
      body: JSON.stringify(param),
      // mode: 'no-cors',
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Content-Type': 'application/json',
        Authorization: 'Bearer ' + token.value,
      },
    })
      .then((res) => {
        return res.json()
      })
      .then((data) => {
        const url = data.data && data.data.url
        if (url) {
          rtspURL.value = url
          resolve()
        } else {
          const errMsg = data.code == 'DV1019' ? '设备能力级不支持！' : data.errMsg
          // this.$message.warning(errMsg)
          console.log(errMsg)
          reject(errMsg)
        }
      })
  })
}

const token = ref('')
const getToken = () => {
  const url = `${base_url}/gateway/auth/oauth/token?grant_type=client_credentials&scope=server&client_id=${config.client_id}&client_secret=${config.client_secret}`
  fetch(url, {
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    method: 'POST',
  })
    .then((res) => {
      return res.json()
    })
    .then((data) => {
      token.value = data.access_token
    })
}

onMounted(() => {
  base_url = import.meta.env.DEV ? '' : config.base_url
  nextTick().then(() => {
    getToken()
    videoPlay.init([player.value])
  })
})

defineExpose({
  play,
  toggleIVS,
})
</script>

<style lang="less" scoped>
.w-100 {
  width: 100%;
}
.h65 {
  height: 65px;
}
.mr-28 {
  margin-right: 28px;
}
.config-set {
  display: flex;
  align-items: center;
  padding: 0 15px;
}
.ant-layout-footer {
  padding: 0;
}
.ant-select {
  width: 180px;
}
.player-container {
  background-color: #ffffff;
  .player-box {
    height: 100%;
    position: relative;
    overflow: hidden;
    background-position: center center;
    background-repeat: no-repeat;
    background: #f2f2f2;
  }
  .main-container {
    height: calc(100% - 85px);
    padding: 0;
    margin-bottom: 20px;
    &.fullscreen {
      height: 100%;
      margin: 0;
    }
  }
  .video-player__default {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -24px;
    margin-top: -24px;
  }
  .ant-layout-footer {
    height: 65px;
    background-color: #ffffff;
    box-shadow: 0px 3px 6px 0px #dde3ee;
    padding: 0px;
    &.fullscreen-tool {
      position: absolute;
      bottom: 0;
      background-color: #000;
      opacity: 0;
      &:hover {
        opacity: 0.7;
      }
      &.show-tools {
        opacity: 0.7;
      }
    }
  }
}
.control-icon {
  outline: none;
  &:hover {
    fill: var(--primary-base);
    color: var(--primary-base);
  }
  &.disabled {
    fill: #c5cdd6;
    color: #c5cdd6;
  }
}
.full-screen {
  position: absolute;
  right: 20px;
  top: 22px;
}
</style>
